//
//  RxViewController.swift
//  RxSwiftExample
//
//  Created by lxf on 2021/11/23.
//

import UIKit

class RxViewController: BaseViewController {
    
    lazy var label: UILabel = {
        let label = UILabel()
        return label
    }()
    
    lazy var button: UIButton = {
        let button = UIButton(type: .custom)
        button.setTitle("按钮", for: .normal)
        button.setTitleColor(.gray, for: .normal)
        button.setTitleColor(.blue, for: .selected)
        return button
    }()
    
    lazy var disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
    
    override func initSubViews() {
        super.initSubViews()
        self.view.addSubview(label)
        self.view.addSubview(button)
    }
    
    override func addConstraints() {
        super.addConstraints()
        
        label.snp.makeConstraints { make in
            make.top.equalTo(self.view)
            make.centerX.equalTo(self.view)
        }
        
        button.snp.makeConstraints { make in
            make.top.equalTo(label.snp.bottom).offset(10)
            make.centerX.equalTo(label)
        }
    }
    
    override func addRxSwift() {
        super.addRxSwift()
        
//        testObservable()
//        testObserverBinder()
        testRxSwiftExtension()
    }
    

}

extension RxViewController {
    
    /// 观察者
    func testObserver() {
        
        /**
         *  1、在 subscribe 方法中创建
         * （1）创建观察者最直接的方法就是在 Observable 的 subscribe 方法后面描述当事件发生时，需要如何做出响应。
         * （2）比如下面的样例，观察者就是由后面的 onNext，onError，onCompleted 这些闭包构建出来的。
         */
        let observable = Observable.of("A", "B", "C")
        observable.subscribe(onNext: { element in
            print(element)
        }, onError: { error in
            print(error)
        }, onCompleted: {
            print("completed")
        }).disposed(by: disposeBag)
        
        /**
         *  2、在 bind 方法中创建
         * （1）下面代码我们创建一个定时生成索引数的 Observable 序列，并将索引数不断显示在 label 标签上：
         */
        // Observable序列（每隔1秒钟发出一个索引数）
        let observable1 = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
        
        // map 方法允许对数据进行一次操作，返回
        // 在 bind 方法中创建：Observer
        observable1
            .map({ interval in
                return "当前索引：\(interval)"
            })
            .share(replay: 1, scope: .whileConnected)
            .bind(onNext: { [weak self] (text: String) in
                self?.label.text = text
            })
            .disposed(by: disposeBag)
    }
    
    /// 观察者
    func testObserverBinder() {
        
        //配合 bindTo 方法使用
        
        // 自定义，UI观察者
        let observer: Binder<String> = Binder(label) { (view, text) in
            view.text = text
        }
        
        // Observable序列（每隔1秒钟发出一个索引数）
        let observable = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
        
        // observable绑定，UI观察者observer
        observable
            .map({"当前索引：\($0)"})
            .bind(to: observer)
            .disposed(by: disposeBag)
        
        // 观察者：label.rx.text
//        observable
//            .map({"当前索引：\($0)"})
//            .bind(to: label.rx.text)
//            .disposed(by: disposeBag)
        
        /**
         * 附：Binder 在 RxCocoa 中的应用
         *（1）其实 RxCocoa 在对许多 UI 控件进行扩展时，就利用 Binder 将控件属性变成观查者，比如 UIControl+Rx.swift 中的 isEnabled 属性便是一个 observer ：
         * import RxSwift
         * import UIKit
          
         extension Reactive where Base: UIControl {
              
             /// Bindable sink for `enabled` property.
             public var isEnabled: Binder<Bool> {
                 return Binder(self.base) { control, value in
                     control.isEnabled = value
                 }
             }
         }
                  
         */
        
        observable
            .map({ $0 % 2 == 0 })
            .bind(to: button.rx.isSelected)
            .disposed(by: disposeBag)
    }
    
    
    ///  Reactive 类进行扩展，自定义可绑定属性。
    func testRxSwiftExtension() {
        
        label.text = "自定义可绑定属性：fontSize"
        
        // Observable序列（每隔1秒钟发出一个索引数）
        let observable = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
        
        observable
            .map({ CGFloat($0) })
            .bind(to: label.rx.fontSize)
            .disposed(by: disposeBag)
        
        label.rx.attributedText
    }
    
    
}
